const WebSocket = require('ws');

//存储客户端玩家
const playerList = []

//响应消息状态码
const MESSAGE_STATE_CODE = {
    createPlayer: 200,  //创建玩家成功
    success: 201, //创建对局成功
    fail: 400, //创建对局失败
    findOpponent: 500, //成功找到对手玩家
    requestMatch: 10001, //请求对局
    updateDrop: 10002,//更新棋盘
    giveUp: 10003,//有人跑了
}

// 客户端 WebSocket 发送消息类型
const webSocketSendCode = {
    findOpponent: 3001, //查找对手
    sendDrop: 3002, //发送落子点
    giveUp: 3003, //投降跑路
    acceptMatch: 3004, //接受对局
    rejectMatch: 3005, //拒绝配对
    sendDropIndex: 3006 // 更新棋盘
}

let GameCounter = 1001 //对局计数器

const gameMap = new Map() //存储对局

// 创建一个WebSocket服务器，监听3000端口
const wss = new WebSocket.Server({ port: 3000 });

// 监听连接请求，为每个客户端分配唯一的ID
wss.on('connection', function connection(ws) {
    // 获取当前时间戳作为玩家连接的id
    ws.id = Date.now();

    console.log(`Client ${ws.id}  connected`);


    //存储玩家
    playerList.push(ws)
    console.log("playerList.length:", playerList.length);

    // 发送玩家id
    ws.send(JSON.stringify({
        type: MESSAGE_STATE_CODE.createPlayer,
        data: ws.id
    }))
    console.log(playerList.map(ws => ws.id));



    // 处理来自客户端的消息和错误事件
    ws.on('message', function incoming(message) {
        const messageObj = JSON.parse(message)
        console.log(messageObj);

        //消息类型为查找对手
        if (messageObj.type === webSocketSendCode.findOpponent) {
            //查找对手
            const opponent = playerList.find((item) => item.id === Number(messageObj.data.opponentID))

            // 对手在线则响应查找成功
            if (opponent) {
                //通知请求方对手在线
                ws.send(JSON.stringify({
                    type: MESSAGE_STATE_CODE.findOpponent
                }))

                //向对手发送请求配对
                opponent.send(JSON.stringify({
                    type: MESSAGE_STATE_CODE.requestMatch,
                    data: ws.id
                }))
            } else {
                //没有该对手则拒绝对战
                ws.send(JSON.stringify({
                    type: MESSAGE_STATE_CODE.fail
                }))
            }
        } else if (messageObj.type === webSocketSendCode.acceptMatch) {
            //创建对局
            gameMap.set(GameCounter, {
                white: messageObj.data.opponentID,
                black: ws.id,
            })

            const white = playerList.find((item) => item.id === +messageObj.data.opponentID)

            //给连接对象添加对局id，方便断开连接时销毁对局
            white.gameId = GameCounter
            ws.gameId = GameCounter

            white.send(JSON.stringify({
                type: MESSAGE_STATE_CODE.success,
                data: {
                    playerIndex: 1,
                    gameId: GameCounter
                }
            }))

            ws.send(JSON.stringify({
                type: MESSAGE_STATE_CODE.success,
                data: {
                    playerIndex: 0,
                    gameId: GameCounter
                }
            }))

            GameCounter++
        } else if (messageObj.type === webSocketSendCode.rejectMatch) {
            //查找对手
            const opponent = playerList.find((item) => item.id === +messageObj.data.opponentID)

            if (opponent) {
                //拒绝对战
                opponent.send(JSON.stringify({
                    type: MESSAGE_STATE_CODE.fail
                }))
            }
        } else if (messageObj.type === webSocketSendCode.sendDropIndex) {
            const playerIDList = gameMap.get(ws.gameId)

            //找到对弈双方更新棋盘
            const white = playerList.find((item) => item.id === playerIDList.white)
            const black = playerList.find((item) => item.id === playerIDList.black)

            white.send(JSON.stringify({
                type: MESSAGE_STATE_CODE.updateDrop,
                data: messageObj.data
            }))

            black.send(JSON.stringify({
                type: MESSAGE_STATE_CODE.updateDrop,
                data: messageObj.data
            }))
        }
    });

    ws.on('error', function error(error) {
        console.error(`Error on client ${ws.id}:`, error);
    });

    // 处理客户端断开连接事件
    ws.on('close', function close() {
        //移除玩家
        const playerIndex = playerList.findIndex((item) => item.id === +ws.id)
        playerList.splice(playerIndex, 1)

        const game = gameMap.get(ws.gameId)

        const whiteId = game?.white ?? null
        const blackId = game?.black ?? null

        const white = playerList.find((item) => item.id === whiteId)
        const black = playerList.find((item) => item.id === blackId)

        //判断是谁断开连接
        if (white) {
            //白子存在则向黑子发送提醒
            white.send(JSON.stringify({
                type: MESSAGE_STATE_CODE.giveUp
            }))

        } else if (black) {
            //黑子存在则向白子发送提醒
            black.send(JSON.stringify({
                type: MESSAGE_STATE_CODE.giveUp
            }))
        }

        //销毁对局
        gameMap.delete(ws.gameId)
        
        console.log("playerList.length:", playerList.length);
        console.log(`Client ${ws.id} disconnected`);
    });


});